[Firebase][iOS] Firebase Crashlytics を導入してみたら環境で分けるのにハマった話
はじめに
CX事業本部の中安です
まいどっ、わてがCX事業本部の中安や!
「Firebase
を触ってみるシリーズ」の続きになります。
ここまでは
- Firebase Authentication で会員機能を作ってみよう
- Firebase Cloud Firestore でプロフィール機能を作ってみよう
- Firebase Hosting でキャンペーンページを作ってみよう
というお題で書かせていただきまして、前回は
を書きましたが、ちょっとCrashlyticsの導入の際にハマったところがあったので、切り出してお話をしようかなと思います。
またもウダウダと書きますが、何かのお役に立てば幸いですやで。
何にハマったのかというと
いったい何にハマったのかというと、タイトルにも書いたのですが「CrashlyticsにおけるFirebaseの環境分け」です。
アプリを開発用環境、ステージング環境、本番環境と分けていて、それぞれにFirebaseのプロジェクトが分かれています。 Firebaseのプロジェクトが分かれているということは設定ファイルも分かれているということです。
基本的に iOS で FirebaseSDK を使って Firebase の機能を使おうとする際には GoogleService-Info.plist
というファイルをプロジェクト上に置きますが、この中にある API Key などの値を環境毎に分けるために、ファイル名の拡張子の前に環境の名前をつけて置いていました。
こんな感じ
そして、そのままでは実行時に怒られてしまうので、AppDelegateでFirebaseの初期化をする際に
import UIKit import Firebase @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure(options: firebaseOptions) return true } private var firebaseOptions: FirebaseOptions { let scheme = (環境名を取ってくる処理 ※割愛) let file = Bundle.main.path( forResource: "GoogleService-Info.\(scheme)", ofType: "plist" ) return FirebaseOptions(contentsOfFile: file!)! } }
このようにどの設定ファイルを選択するかを環境毎に分岐させていました。
これで、Firebaseの諸機能を使うには何の問題もなかったのですが、前回のプログの手順でやってみたところ
Could not get GOOGLE_APP_ID in Google Services file from build environment.
というエラーが発生してしまいました。
「GOOGLE_APP_ID
がファイルから取得できない」だと? plistには間違いなくGOOGLE_APP_ID
が存在してるのに…。と、そんな感じで少しだけハマってしまいました。
解決へ
分かってみると、そりゃそうだ
先程書いた AppDelegate での FirebaseSDK の初期化処理はもちろん
application(_: didFinishLaunchingWithOptions:)
に来たときに初めて読み込むファイルが分岐します。
前ブログでも書いたように ScriptPhase のスクリプトが実行されて Crashlytics の初期化が行われるとのことなので、
設定ファイルの読み込みはそれよりも以前のビルドのタイミングで行われ、その際には規定通りGoogleService-Info.plist
ファイルを見に行こうとします。
つまり、環境ごとに分けていたファイルが意味のないことになってしまってたのですね。
では、どうしよう
この問題を解決したいが、Crashlyticsを導入するだけのために今のファイル構成を変えたりイジったりするのはイヤだなぁということで
ビルド時にCrashlytics初期化が実行される前にGoogleService-Info.plist
を作ってしまうという手をとることにしました。
下図のように新しく RunScript を追加して
そのスクリプトには以下のように書きました。
PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/hoge/fuga" case "${CONFIGURATION}" in "Develop" ) cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info.develop.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;; "Staging" ) cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info.staging.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;; "Product" ) cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info.product.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;; "Release" ) cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info.product.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;; *) ;; esac
このスクリプトの最初にある
PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/hoge/fuga"
は、それぞれの設定ファイルが置いてあるディレクトリパスを、プロジェクトルートディレクトリを元に定義しています。
プロジェクトによって異なるとは思うので、適宜書き換えます。
case
の ${CONFIGURATION}
には、下図のプロジェクトの Configurations のいずれかが入ってきます。
そして、GoogleService-Info.(環境名).plist
ファイルをビルドされて出来上がるアプリの中にGoogleService-Info.plist
の名前にしてコピーしておくわけです。
ビルド時にCrashlytics初期化前にこのスクリプトが走ることで、Crashlyticsは環境毎のGoogleService-Info.plist
を読み込むことになります。
ですので、Crashlytics初期化スクリプトよりも上にこのRunScriptは置いておいたほうが良さそうです。
解決
この一手間を加えることによって、Could not get GOOGLE_APP_ID in Google Services file from build environment.
というエラーは消え、環境毎のファイルをいじることもなく、環境毎のFirebaseCrashlyticsにクラッシュログを残すことが出来ました。
最後に
FirebaseCrashlyticsを環境毎に分けたいときに、同じようなエラーになって困った方の助けになれば幸いですやで
参考記事
Use different GoogleService-Info.plist for different build schemes